/*!
 Temelia - Graph Vertex implementation source file.

 Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "include/vertex.h"
#include <stdio.h>
#include <stdlib.h>

struct _vertex_t
{
	/*! label */
	char *label;

	/*! cost */
	double cost;

	/*! identifier */
	unsigned int identifier;

	/*! key */
	void *key;

	/*! color */
	int color;

	/*! if 1 vertex visited and 0 if not explored */
	int visited;

	/*! parent identifier */
	unsigned int parent_identifier;

	/*! time when vertex was discovered by travel */
	unsigned int time_start;

	/*! time when travel finished visiting this vertex */
	unsigned int time_stop;
};

vertex_t vertex_new(char *label, unsigned int identifier, void *key)
{
	vertex_t vertex = (struct _vertex_t *) _new(sizeof(struct _vertex_t));

	// Set current label
	vertex->label = label;

	// Set current key
	vertex->key = key;

	// Default color is WHITE
	vertex->color = WHITE;

	// Default cost is 0
	vertex->cost = 0;

	// Set current identifier
	vertex->identifier = identifier;

	// Default parent is -1
	vertex->parent_identifier = (unsigned int) -1;

	// Default time start and time stop are 0
	vertex->time_start = vertex->time_stop = 0;

	// Default the node is not visited
	vertex->visited = 0;

	return vertex;
}

void vertex_delete(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->visited = vertex->time_start = vertex->time_stop
			= vertex->parent_identifier = vertex->identifier = vertex->color = 0;
	vertex->cost = 0;

	vertex->key = vertex->label = NULL;
	_delete(vertex);
}

char *vertex_get_label(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, NULL);

	return vertex->label;
}

double vertex_get_cost(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, 0);

	return vertex->cost;
}

unsigned int vertex_get_identifier(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, -1);

	return vertex->identifier;
}

void *vertex_get_key(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, NULL);

	return vertex->key;
}

int vertex_get_color(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, -1);

	return vertex->color;
}

int vertex_get_visited(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, -1);

	return vertex->visited;
}

unsigned int vertex_get_parent_identifier(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, -1);

	return vertex->parent_identifier;
}

unsigned int vertex_get_time_start(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, -1);

	return vertex->time_start;
}

unsigned int vertex_get_time_stop(vertex_t vertex)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER, -1);

	return vertex->time_stop;
}

void vertex_set_label(vertex_t vertex, char *label)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->label = label;
}

void vertex_set_cost(vertex_t vertex, double cost)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->cost = cost;
}

void vertex_set_identifier(vertex_t vertex, unsigned int identifier)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->identifier = identifier;
}

void vertex_set_key(vertex_t vertex, void *key)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->key = key;
}

void vertex_set_color(vertex_t vertex, int color)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->color = color;
}

void vertex_set_visited(vertex_t vertex, int visited)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->visited = visited;
}

void vertex_set_parent_identifier(vertex_t vertex,
		unsigned int parent_identifier)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->parent_identifier = parent_identifier;
}

void vertex_set_time_start(vertex_t vertex, unsigned int time_start)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->time_start = time_start;
}

void vertex_set_time_stop(vertex_t vertex, unsigned int time_stop)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);

	vertex->time_stop = time_stop;
}

void vertex_debug(vertex_t vertex, void *stream)
{
	_ASSERT(vertex, ==, NULL, NULL_POINTER,);
	_ASSERT(stream, ==, NULL, NULL_POINTER,);

	fprintf(
			stream,
			"id %u, label %s, cost %lf, key %p, color %d, visited %d, parent %u, time start %u, time stop %u\n",
			vertex->identifier, vertex->label, vertex->cost, vertex->key,
			(int) vertex->color, (int) vertex->visited,
			vertex->parent_identifier, vertex->time_start, vertex->time_stop);
}
